package com.hxexp.weixin.aop.api;

import java.util.LinkedHashMap;
import java.util.Map;

import org.aspectj.lang.JoinPoint;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.hxexp.weixin.hpe.api.addbind.AddBindAPI;
import com.hxexp.weixin.hpe.api.addbind.model.AddBindParamBean;
import com.hxexp.weixin.hpe.api.addbind.model.AddBindResultBean;
import com.hxexp.weixin.hpe.api.addpassenger.AddPassengerAPI;
import com.hxexp.weixin.hpe.api.addpassenger.model.AddPassengerParamBean;
import com.hxexp.weixin.hpe.api.addpassenger.model.AddPassengerResultBean;
import com.hxexp.weixin.hpe.api.arrivestations.ArriveStationsAPI;
import com.hxexp.weixin.hpe.api.arrivestations.model.ArriveStationsParamBean;
import com.hxexp.weixin.hpe.api.arrivestations.model.ArriveStationsResultBean;
import com.hxexp.weixin.hpe.api.authenticode.AccountAuthenticodeAPI;
import com.hxexp.weixin.hpe.api.authenticode.model.AccountAuthenticodeParamBean;
import com.hxexp.weixin.hpe.api.authenticode.model.AccountAuthenticodeResultBean;
import com.hxexp.weixin.hpe.api.bindpassenger.BindPassengerAPI;
import com.hxexp.weixin.hpe.api.bindpassenger.model.BindPassengerParamBean;
import com.hxexp.weixin.hpe.api.bindpassenger.model.BindPassengerResultBean;
import com.hxexp.weixin.hpe.api.delbind.DelBindAPI;
import com.hxexp.weixin.hpe.api.delbind.model.DelBindParamBean;
import com.hxexp.weixin.hpe.api.delbind.model.DelBindResultBean;
import com.hxexp.weixin.hpe.api.delpassenger.DelPassengerAPI;
import com.hxexp.weixin.hpe.api.delpassenger.model.DelPassengerParamBean;
import com.hxexp.weixin.hpe.api.delpassenger.model.DelPassengerResultBean;
import com.hxexp.weixin.hpe.api.login.LoginAPI;
import com.hxexp.weixin.hpe.api.login.model.LoginParamBean;
import com.hxexp.weixin.hpe.api.login.model.LoginResultBean;
import com.hxexp.weixin.hpe.api.orderdetail.OrderDetailAPI;
import com.hxexp.weixin.hpe.api.orderdetail.model.OrderDetailParamBean;
import com.hxexp.weixin.hpe.api.orderdetail.model.OrderDetailResultBean;
import com.hxexp.weixin.hpe.api.orderpayment.OrderPaymentAPI;
import com.hxexp.weixin.hpe.api.orderpayment.model.PrepayOrderParamBean;
import com.hxexp.weixin.hpe.api.orderpayment.model.PrepayOrderResultBean;
import com.hxexp.weixin.hpe.api.ordersubmit.OrderSubmitAPI;
import com.hxexp.weixin.hpe.api.ordersubmit.model.OrderSubmitParamBean;
import com.hxexp.weixin.hpe.api.ordersubmit.model.OrderSubmitResultBean;
import com.hxexp.weixin.hpe.api.passengerlist.PassengerListAPI;
import com.hxexp.weixin.hpe.api.passengerlist.model.PassengerListParamBean;
import com.hxexp.weixin.hpe.api.passengerlist.model.PassengerListResultBean;
import com.hxexp.weixin.hpe.api.querybind.QueryBindAPI;
import com.hxexp.weixin.hpe.api.querybind.model.QueryBindParamBean;
import com.hxexp.weixin.hpe.api.querybind.model.QueryBindResultBean;
import com.hxexp.weixin.hpe.api.querypassenger.QueryPassengerAPI;
import com.hxexp.weixin.hpe.api.querypassenger.model.QueryPassengerParamBean;
import com.hxexp.weixin.hpe.api.querypassenger.model.QueryPassengerResultBean;
import com.hxexp.weixin.hpe.api.refund.RefundAPI;
import com.hxexp.weixin.hpe.api.refund.model.RefundParamBean;
import com.hxexp.weixin.hpe.api.refund.model.RefundResultBean;
import com.hxexp.weixin.hpe.api.register.RegisterAPI;
import com.hxexp.weixin.hpe.api.register.model.RegisterParamBean;
import com.hxexp.weixin.hpe.api.register.model.RegisterResultBean;
import com.hxexp.weixin.hpe.api.resetpwd.ResetPwdAPI;
import com.hxexp.weixin.hpe.api.resetpwd.model.ResetPwdParamBean;
import com.hxexp.weixin.hpe.api.resetpwd.model.ResetPwdResultBean;
import com.hxexp.weixin.hpe.api.returnamount.ReturnAmountAPI;
import com.hxexp.weixin.hpe.api.returnamount.model.ReturnAmountParamBean;
import com.hxexp.weixin.hpe.api.returnamount.model.ReturnAmountResultBean;
import com.hxexp.weixin.hpe.api.sendcaptcha.SendCaptchaAPI;
import com.hxexp.weixin.hpe.api.sendcaptcha.model.SendCaptchaParamBean;
import com.hxexp.weixin.hpe.api.sendcaptcha.model.SendCaptchaResultBean;
import com.hxexp.weixin.hpe.api.startstations.StartStationsAPI;
import com.hxexp.weixin.hpe.api.startstations.model.StartStationsParamBean;
import com.hxexp.weixin.hpe.api.startstations.model.StartStationsResultBean;
import com.hxexp.weixin.hpe.api.trafficline.TrafficLineAPI;
import com.hxexp.weixin.hpe.api.trafficline.model.TrafficLineParamBean;
import com.hxexp.weixin.hpe.api.trafficline.model.TrafficLineResultBean;
import com.hxexp.weixin.hpe.api.updatepassenger.UpdatePassengerAPI;
import com.hxexp.weixin.hpe.api.updatepassenger.model.UpdatePassengerParamBean;
import com.hxexp.weixin.hpe.api.updatepassenger.model.UpdatePassengerResultBean;
import com.hxexp.weixin.hpe.api.userorderlist.UserOrderListAPI;
import com.hxexp.weixin.hpe.api.userorderlist.model.UserOrderListParamBean;
import com.hxexp.weixin.hpe.api.userorderlist.model.UserOrderListResultBean;
import com.hxexp.weixin.hpe.api.userupdate.UserUpdateAPI;
import com.hxexp.weixin.hpe.api.userupdate.model.UserUpdateParamBean;
import com.hxexp.weixin.hpe.api.userupdate.model.UserUpdateResultBean;

/**
 * HPE API 组件日志帮助类
 *
 * @author li.jiang
 *
 */
public final class APILogHelper {
    private static final Logger LOGGER = LoggerFactory.getLogger(APILogHelper.class);
    private static final Map<String, String> PARAM_LOGFORMAT_MAP = new LinkedHashMap<String, String>();
    private static final Map<String, String> RESULT_LOGFORMAT_MAP = new LinkedHashMap<String, String>();
    private static final Map<String, String> EXCEPTION_LOGMSG_MAP = new LinkedHashMap<String, String>();

    static {
        PARAM_LOGFORMAT_MAP.put(AddBindParamBean.class.getName(), "***********添加微信用户和HPE用户绑定关系接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(AddBindResultBean.class.getName(), "***********添加微信用户和HPE用户绑定关系接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(AddBindAPI.class.getName(), "调用【添加微信用户和HPE用户绑定关系接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(AddPassengerParamBean.class.getName(), "***********新建常用乘车人接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(AddPassengerResultBean.class.getName(), "***********新建常用乘车人接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(AddPassengerAPI.class.getName(), "调用【新建常用乘车人接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(ArriveStationsParamBean.class.getName(), "***********到达站列表接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(ArriveStationsResultBean.class.getName(), "***********到达站列表接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(ArriveStationsAPI.class.getName(), "调用【到达站列表接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(AccountAuthenticodeParamBean.class.getName(), "***********发送更新用户信息验证码接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(AccountAuthenticodeResultBean.class.getName(), "***********发送更新用户信息验证码接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(AccountAuthenticodeAPI.class.getName(), "调用【发送更新用户信息验证码接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(BindPassengerParamBean.class.getName(), "***********绑定乘客接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(BindPassengerResultBean.class.getName(), "***********绑定乘客接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(BindPassengerAPI.class.getName(), "调用【绑定乘客接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(DelBindParamBean.class.getName(), "***********解除微信用户和HPE用户绑定关系接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(DelBindResultBean.class.getName(), "***********解除微信用户和HPE用户绑定关系接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(DelBindAPI.class.getName(), "调用【解除微信用户和HPE用户绑定关系接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(DelPassengerParamBean.class.getName(), "***********删除常用乘车人接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(DelPassengerResultBean.class.getName(), "***********删除常用乘车人接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(DelPassengerAPI.class.getName(), "调用【删除常用乘车人接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(LoginParamBean.class.getName(), "***********用户登录接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(LoginResultBean.class.getName(), "***********用户登录接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(LoginAPI.class.getName(), "调用【用户登录接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(OrderDetailParamBean.class.getName(), "***********订单详情接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(OrderDetailResultBean.class.getName(), "***********订单详情接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(OrderDetailAPI.class.getName(), "调用【订单详情接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(PrepayOrderParamBean.class.getName(), "***********预支付订单接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(PrepayOrderResultBean.class.getName(), "***********预支付订单接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(OrderPaymentAPI.class.getName(), "调用【预支付订单接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(OrderSubmitParamBean.class.getName(), "***********生成订单接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(OrderSubmitResultBean.class.getName(), "***********生成订单接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(OrderSubmitAPI.class.getName(), "调用【生成订单接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(PassengerListParamBean.class.getName(), "***********常用乘车人列表接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(PassengerListResultBean.class.getName(), "***********常用乘车人列表接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(PassengerListAPI.class.getName(), "调用【常用乘车人列表接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(QueryBindParamBean.class.getName(), "***********查询微信用户和HPE用户绑定关系接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(QueryBindResultBean.class.getName(), "***********查询微信用户和HPE用户绑定关系接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(QueryBindAPI.class.getName(), "调用【查询微信用户和HPE用户绑定关系接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(QueryPassengerParamBean.class.getName(), "***********查询常用乘车人接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(QueryPassengerResultBean.class.getName(), "***********查询常用乘车人接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(QueryPassengerAPI.class.getName(), "调用【查询常用乘车人接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(RefundParamBean.class.getName(), "***********退票接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(RefundResultBean.class.getName(), "***********退票接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(RefundAPI.class.getName(), "调用【退票接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(RegisterParamBean.class.getName(), "***********用户注册接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(RegisterResultBean.class.getName(), "***********用户注册接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(RegisterAPI.class.getName(), "调用【用户注册接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(ResetPwdParamBean.class.getName(), "***********重置密码接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(ResetPwdResultBean.class.getName(), "***********重置密码接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(ResetPwdAPI.class.getName(), "调用【重置密码接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(ReturnAmountParamBean.class.getName(), "***********可退金额接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(ReturnAmountResultBean.class.getName(), "***********可退金额接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(ReturnAmountAPI.class.getName(), "调用【可退金额接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(SendCaptchaParamBean.class.getName(), "***********发送重置密码验证码接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(SendCaptchaResultBean.class.getName(), "***********发送重置密码验证码接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(SendCaptchaAPI.class.getName(), "调用【发送重置密码验证码接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(StartStationsParamBean.class.getName(), "***********出发站列表接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(StartStationsResultBean.class.getName(), "***********出发站列表接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(StartStationsAPI.class.getName(), "调用【出发站列表接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(TrafficLineParamBean.class.getName(), "***********查询车次接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(TrafficLineResultBean.class.getName(), "***********查询车次接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(TrafficLineAPI.class.getName(), "调用【查询车次接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(UpdatePassengerParamBean.class.getName(), "***********修改常用乘车人接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(UpdatePassengerResultBean.class.getName(), "***********修改常用乘车人接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(UpdatePassengerAPI.class.getName(), "调用【修改常用乘车人接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(UserOrderListParamBean.class.getName(), "***********用户订单列表接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(UserOrderListResultBean.class.getName(), "***********用户订单列表接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(UserOrderListAPI.class.getName(), "调用【用户订单列表接口】发生异常");

        PARAM_LOGFORMAT_MAP.put(UserUpdateParamBean.class.getName(), "***********修改用户信息接口【参数】：{}");
        RESULT_LOGFORMAT_MAP.put(UserUpdateResultBean.class.getName(), "***********修改用户信息接口【返回结果】：{}");
        EXCEPTION_LOGMSG_MAP.put(UserUpdateAPI.class.getName(), "调用【修改用户信息接口】发生异常");
    }

    private APILogHelper() {
    }

    /**
     * 获取参数日志格式字符串
     *
     * @param paramClassName
     *            参数类名
     * @return 日志格式字符串
     */
    private static String getParamLogFormat(String paramClassName) {
        String logFormat = PARAM_LOGFORMAT_MAP.get(paramClassName);
        if (null == logFormat) {
            logFormat = String.format("【%s】：{}", paramClassName); // NOSONAR
        }

        return logFormat;
    }

    /**
     * 获取返回结果日志格式字符串
     *
     * @param resultClassName
     *            返回结果类名
     * @return 日志格式字符串
     */
    private static String getResultLogFormat(String resultClassName) {
        String logFormat = RESULT_LOGFORMAT_MAP.get(resultClassName);
        if (null == logFormat) {
            logFormat = String.format("【%s】：{}", resultClassName); // NOSONAR
        }

        return logFormat;
    }

    /**
     * 获取异常日志信息
     *
     * @param interfaceClassName
     *            接口类名
     * @return 异常日志信息
     */
    private static String getExceptionLogMsg(String interfaceClassName) {
        String logMsg = EXCEPTION_LOGMSG_MAP.get(interfaceClassName);
        if (null == logMsg) {
            logMsg = String.format("调用【%s】发生异常", interfaceClassName);
        }

        return logMsg;
    }

    /**
     * 记录异常抛出信息
     *
     * @param joinPoint
     *            连接点
     * @param ex
     *            异常
     */
    public static void logAPIException(JoinPoint joinPoint, Exception ex) {
        LOGGER.error(getExceptionLogMsg(joinPoint.getSignature().getDeclaringTypeName()), ex);
    }

    /**
     * 记录接口参数信息
     *
     * @param joinPoint
     *            连接点
     */
    public static void logAPIParam(JoinPoint joinPoint) {
        for (Object paramObj : joinPoint.getArgs()) {
            LOGGER.info(getParamLogFormat(paramObj.getClass().getName()), paramObj);
        }
    }

    /**
     * 记录接口返回值信息
     *
     * @param returnValue
     *            接口返回值
     */
    public static void logAPIResult(Object returnValue) {
        LOGGER.info(getResultLogFormat(returnValue.getClass().getName()), returnValue);
    }

    public static Logger getLogger() {
        return LOGGER;
    }
}
